﻿// -----------------------------------------------------------------------
// <copyright file="Library_Core.cs" company="G.W. van der Vegt">
// SharpForth is inspired by JonesForthInC v1.48 and bb4wForth.
// </copyright>
// -----------------------------------------------------------------------
namespace SharpForth
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// This class contains the definitions of some additional pure Forth Words.
    /// 
    /// These defintions are parsed in the order in which defined (thats why they are 
    /// numbered, so sorting the class does not ruin everything). 
    /// 
    /// Maybe it can be solved by adding dependencies like in Words!
    /// 
    /// //! NOTE: In order to match Lazy&lt;Dictionary&gt; and the actual Forth Word defined in the 
    /// //!       DictionaryEntry, the Description Attribute must match the name of the Forth Word defined.
    /// //!       This because Forth Words have a different allowed syntax than C# Identifiers used for the 
    /// //!       Lazy&lt;Dictionary&gt;. It's used for both resolving Depends Attributes and the Forth SYNTAX Word.
    /// </summary>
    public static partial class Library
    {
        #region Fields

        /// <summary>
        /// 
        /// </summary>
        [WordName("HERE")]
        [WordSet(WordSets.CORE)]
        [Depends("DP")]
        [Depends("@")]
        [Syntax("( -- addr )")]
        internal static String HERE = ": HERE DP @ ;\n";

        /// <summary>
        /// 3283 - condition IF true-part THEN rest
        ///        condition IF true-part ELSE false-part THEN rest
        ///        10 TRUE IF 1 + ELSE 1 - THEN . ;
        /// </summary>
        [WordName("IF")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("0BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Syntax("( x -- )")]
        internal static String IF = ": IF IMMEDIATE ['] 0BRANCH , HERE 0 , ;\n";

        /// <summary>
        /// 3197 - NEGATE leaves the negative of a number on the stack.
        /// </summary>
        [WordName("NEGATE")]
        [WordSet(WordSets.CORE)]
        [Depends("SWAP")]
        [Depends("-")]
        [Syntax("( n1 -- n2 )")]
        internal static String NEGATE = ": NEGATE 0 SWAP - ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("THEN")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("DUP")]
        [Depends("DP")]
        [Depends("@")]
        [Depends("SWAP")]
        [Depends("-")]
        [Depends("!")]
        [Syntax("( -- )")]
        internal static String THEN = ": THEN IMMEDIATE DUP DP @ SWAP - SWAP ! ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("ABS")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("DUP")]
        [Depends("0<")]
        [Depends("IF")]
        [Depends("NEGATE")]
        [Depends("THEN")]
        [Syntax("( n -- u )")]
        internal static String ABS = ": ABS ( n -- u) DUP 0< IF NEGATE THEN ;\n";

        /// <summary>
        /// 3325 - BEGIN loop-part AGAIN
        ///        Note: An endless loop, that needs EXIT to return.
        ///        : V BEGIN 10 . AGAIN ;
        ///</summary>
        [WordName("AGAIN")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("-")]
        [Syntax("( -- )")]
        internal static String AGAIN = ": AGAIN IMMEDIATE ['] BRANCH , HERE - , ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("ALIGN")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("HERE")]
        [Depends("ALIGNED")]
        [Depends("DP")]
        [Depends("!")]
        [Syntax("( -- )")]
        internal static String ALIGN =
        "  ( ALIGN aligns the DP pointer, so the next word appended will be aligned properly.)\n" +
        ": ALIGN HERE ALIGNED DP ! ;\n";

        /// <summary>
        /// Memory Alignment.
        /// </summary>
        [WordName("ALIGNED")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("+")]
        [Depends("INVERT")]
        [Depends("AND")]
        [Syntax("( addr -- a-addr )")]
        internal static String ALIGNED =
        "  ( ALIGNED takes an address and rounds it up (aligns it) to the next 4 byte boundary.)\n" +
        ": ALIGNED                  ( addr -- addr )\n" +
        "    3 + 3 INVERT AND       ( (addr+3) & ~3 )\n" +
        ";\n";

        /// <summary>
        /// 3305 - BEGIN loop-part condition UNTIL
        ///        : V 10 1 - DUP . DUP 0= 0BRANCH ( -32 ) ;
        /// </summary>
        [WordName("BEGIN")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("HERE")]
        [Syntax("( -- )")]
        internal static String BEGIN = ": BEGIN IMMEDIATE HERE ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("BL")]
        [WordSet(WordSets.CORE)]
        [Syntax("( -- char )")]
        internal static String BL = ": BL 32 ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("[CHAR]")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("CHAR")]
        [Depends("[']")]
        [Depends("LIT")]
        [Depends(",")]
        [Syntax("<spaces>name -- ) ( -- char )")]
        internal static String BRACKET_CHAR = ": [CHAR] IMMEDIATE CHAR ['] LIT , , ;\n";

        /// <summary>
        /// While compiling, '[COMPILE] word' compiles 'word' if it would otherwise be IMMEDIATE.
        /// </summary>
        [WordName("[COMPILE]")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("IMMEDIATE")]
        [Depends("WORD")]
        [Depends("FIND")]
        [Depends(">CFA")]
        [Depends(",")]
        [Syntax(" \"<spaces>name\" -- )")]
        internal static String BRACKET_COMPILE = ": [COMPILE] IMMEDIATE WORD FIND >CFA , ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("UNTIL")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("0BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("-")]
        [Depends(",")]
        [Syntax("( -- )")]
        internal static String BRACKET_TICK = ": UNTIL IMMEDIATE ['] 0BRANCH , HERE -  , ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CASE")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("IMMEDIATE")]
        [Syntax("( -- )")]
        internal static String CASE =
        ": CASE IMMEDIATE\n" +
        "    0               ( push 0 to mark the bottom of the stack )\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CELLS")]
        [WordSet(WordSets.CORE)]
        [Syntax("( n1 -- n2 )")]
        [Depends("(")]
        [Depends("*")]
        internal static String CELLS = ": CELLS ( n -- 4*n ) 4 * ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CELL+")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("CELLS")]
        [Depends("+")]
        [Syntax("( a-addr1 -- a-addr2 )")]
        internal static String CELL_PLUS =
         ": CELL+ ( a-addr1 -- a-addr2 ) 1 CELLS + ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CHARS")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Syntax("( n1 -- n2 )")]
        internal static String CHARS = ": CHARS ( n1 -- n2 ) ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CHAR+")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("CHARS")]
        [Depends("+")]
        [Syntax("( c-addr1 -- c-addr2 )")]
        internal static String CHAR_PLUS =
        ": CHAR+ ( c-addr1 -- c-addr2 ) 1 CHARS + ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("CR")]
        [WordSet(WordSets.CORE)]
        [Depends("'\\r'")]
        [Depends("EMIT")]
        [Syntax("( -- )")]
        internal static String CR = ": CR '\\r' EMIT '\\n' EMIT ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("DECIMAL")]
        [WordSet(WordSets.CORE)]
        [Depends("BASE")]
        [Depends("!")]
        [Syntax("( -- )")]
        internal static String DECIMAL = ": DECIMAL 10 BASE ! ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("DO")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("(DO)")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("IMMEDIATE")]
        [Syntax("( n1|u1 n2|u2 -- ) ( R: -- loop-sys")]
        internal static String DO =
        "(\n" +
        "  DO \n" +
        "  Compilation: ( C: -- do-sys )\n" +
        "   \n" +
        "   Place do-sys onto the control-flow stack. Append the run-time semantics \n" +
        "   given below to the current definition. The semantics are incomplete until \n" +
        "   resolved by a consumer of do-sys such as LOOP.\n" +
        "   \n" +
        "	Run-time: ( n1|u1 n2|u2 -- ) ( R: -- loop-sys )\n" +
        "   \n" +
        "   Set up loop control parameters with index n2|u2 and limit n1|u1. \n" +
        "   An ambiguous condition exists if n1|u1 and n2|u2 are not both the \n" +
        "   same type. Anything already on the return stack becomes unavailable \n" +
        "   until the loop-control parameters are discarded. \n" +
        ")\n" +
        ": DO    ( -- here 0 )\n" +
        "    ['] (DO) , \n" +
        "    HERE 0 \n" +
        "; IMMEDIATE\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("LEAVE")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("UNLOOP")]
        [Depends(",")]
        [Depends("BRANCH")]
        [Depends("LEAVE-SP")]
        [Depends("@")]
        [Depends("CELLS")]
        [Depends("(")]
        [Depends(">")]
        [Depends("IF")]
        [Depends("ABORT")]
        [Depends("THEN")]
        [Depends("HERE")]
        [Depends("+!")]
        [Depends("@")]
        [Depends("!")]
        [Depends("IMMEDIATE")]
        [Syntax("( -- ) ( R: loop-sys -- )")]
        internal static String LEAVE =
        "(\n" +
        "  LEAVE Discard the current loop control parameters. An ambiguous condition exists if they \n" +
        "  are unavailable. Continue execution immediately following the innermost syntactically \n" +
        "  enclosing DO ... LOOP or DO ... +LOOP. \n" +
        ")\n" +
        ": LEAVE                               \n" +
        "    ['] UNLOOP ,                      \n" +
        "    ['] BRANCH ,                      \n" +
        "    LEAVE-SP @ LEAVE-SP - 31 CELLS >  \n" +
        "    IF ABORT THEN                     \n" +
        "    1 CELLS LEAVE-SP +!               \n" +
        "    HERE LEAVE-SP @ !                 \n" +
        "    0 ,                               \n" +
        "; IMMEDIATE\n ";

        /// <summary>
        /// 
        /// </summary>
        [WordName("LOOP")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("(LOOP)")]
        [Depends("RESOLVE-DO")]
        [Depends("RESOLVE-LEAVES")]
        [Depends("IMMEDIATE")]
        [Syntax("( -- ) ( R: loop-sys1 -- | loop-sys2 )")]
        internal static String LOOP =
        "(\n" +
        " LOOP \n" +
        "	Compilation: ( C: do-sys -- )\n" +
        "   \n" +
        "   Append the run-time semantics given below to the current definition. Resolve the \n" +
        "   destination of all unresolved occurrences of LEAVE between the location given by \n" +
        "   do-sys and the next location for a transfer of control, to execute the words following\n" +
        "   the LOOP.\n" +
        "   \n" +
        "   Run-time: ( -- ) ( R:  loop-sys1 --  | loop-sys2 ) \n" +
        "   \n" +
        "   An ambiguous condition exists if the loop control parameters are unavailable. \n" +
        "   Add one to the loop index. If the loop index is then equal to the loop limit, \n" +
        "   discard the loop parameters and continue execution immediately following the loop. \n" +
        "   Otherwise continue execution at the beginning of the loop. \n" +
        ")\n" +
        ": LOOP   ( here 0|1 -- ) \n" +
        "    ['] (LOOP) ,         \n" +
        "    RESOLVE-DO           \n" +
        "    RESOLVE-LEAVES       \n" +
        "; IMMEDIATE\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName(".(")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("BEGIN")]
        [Depends("KEY")]
        [Depends("DUP")]
        [Depends("')'")]
        [Depends("=")]
        [Depends("IF")]
        [Depends("DROP")]
        [Depends("EXIT")]
        [Depends("THEN")]
        [Depends("EMIT")]
        [Depends("AGAIN")]
        [Depends("IMMEDIATE")]
        [Syntax("( ud1 -- ud2 )")]
        internal static String DOT_PAREN =
        ": .( ( \"ccc<paren>\" -- )\n" +
        "  BEGIN KEY DUP ')' = IF DROP EXIT THEN EMIT AGAIN\n" +
        "; IMMEDIATE\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("ELSE")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("SWAP")]
        [Depends("DUP")]
        [Depends("-")]
        [Depends("!")]
        [Syntax("( -- )")]
        internal static String ELSE = ": ELSE IMMEDIATE ['] BRANCH , HERE 0 , SWAP DUP HERE SWAP - SWAP ! ;\n";

        /// <summary>
        /// String Printing.
        /// </summary>
        [WordName(".\"")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("IMMEDIATE")]
        [Depends("STATE")]
        [Depends("@")]
        [Depends("IF")]
        [Depends("[COMPILE]")]
        [Depends("S\"")]
        [Depends("[']")]
        [Depends("TYPE")]
        [Depends("ELSE")]
        [Depends("BEGIN")]
        [Depends("KEY")]
        [Depends("DUP")]
        [Depends("DROP")]
        [Depends("EXIT")]
        [Depends("THEN")]
        [Depends("EMIT")]
        [Depends("AGAIN")]
        [Syntax("( \"ccc<quote>\" -- )")]
        internal static String DOT_QUOTE =
        "  ( \n" +
        "    .\" is the print string operator in FORTH.  Example: .\" Something to print\"\n" +
        "    The space after the operator is the ordinary space required between words \n" +
        "    and is not a part of what is printed.\n" +
        "    \n" +
        "    In immediate mode we just keep reading characters and printing them until \n" +
        "    we get to the next double quote.\n" +
        "    \n" +
        "    In compile mode we use S\" to store the string, then add TYPE afterwards:\n" +
        "        LITSTRING <string length> <string rounded up to 4 bytes> TYPE\n" +
        "    \n" +
        "    It may be interesting to note the use of [COMPILE] to turn the call to the \n" +
        "    immediate word S\" into compilation of that word.  It compiles it into the \n" +
        "    definition of .\\n\"+ not into the definition of the word being compiled when \n" +
        "    this is running (complicated enough for you?)\n" +
        "  )\n" +
        ": .\" IMMEDIATE            ( -- )\n" +
        "    STATE @ IF             ( compiling? )\n" +
        "        [COMPILE] S\"      ( read the string, and compile LITSTRING, etc. )\n" +
        "        ['] TYPE ,         ( compile the final TYPE )\n" +
        "    ELSE\n" +
        "        ( In immediate mode, just read characters and print them until we get\n" +
        "          to the ending double quote. )\n" +
        "        BEGIN\n" +
        "            KEY\n" +
        "            DUP '\"' = IF\n" +
        "                DROP       ( drop the double quote character )\n" +
        "                EXIT       ( return from this function )\n" +
        "            THEN\n" +
        "            EMIT\n" +
        "        AGAIN\n" +
        "    THEN\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("SPACE")]
        [WordSet(WordSets.CORE)]
        [Depends("BL")]
        [Depends("EMIT")]
        [Syntax("( -- )")]
        internal static String SPACE = ": SPACE BL EMIT ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("REPEAT")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("-")]
        [Depends(",")]
        [Depends("DUP")]
        [Depends("SWAP")]
        [Depends("!")]
        [Syntax("( C: orig dest -- )")]
        internal static String REPEAT = ": REPEAT IMMEDIATE ['] BRANCH , HERE - , DUP HERE SWAP - SWAP ! ;\n";

        /// <summary>
        /// 3331 - BEGIN condition WHILE loop-part REPEAT
        ///        : V 10 BEGIN 1- ?DUP WHILE DUP . REPEAT ;
        ///</summary>
        [WordName("WHILE")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("0BRANCH")]
        [Depends(",")]
        [Depends("HERE")]
        [Depends("SWAP")]
        [Syntax("( -- )")]
        internal static String WHILE = ": WHILE IMMEDIATE ['] 0BRANCH , HERE SWAP 0 , ;\n";

        /// <summary>
        /// 3412 - Space Printing.
        /// </summary>
        [WordName("SPACES")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("BEGIN")]
        [Depends("DUP")]
        [Depends("0>")]
        [Depends("WHILE")]
        [Depends("SPACE")]
        [Depends("1-")]
        [Depends("REPEAT")]
        [Depends("DROP")]
        [Syntax("( n -- )")]
        internal static String SPACES =
            "  ( With the looping constructs, we can now write SPACES, which writes n spaces to stdout. )\n" +
            ": SPACES                   ( n -- )\n" +
            "    BEGIN\n" +
            "        DUP 0>             ( while n > 0 )\n" +
            "    WHILE\n" +
            "        SPACE              ( print a space )\n" +
            "        1-                 ( until we count down to 0 )\n" +
            "    REPEAT\n" +
            "    DROP\n" +
            ";\n";

        /// <summary>
        /// 3325 - Prints a signed number, padded to a certain width.
        /// 
        /// The standard FORTH word . (DOT) is very important.  It takes the number at the top
        /// of the stack and prints it out.  However first I'm going to implement some lower-level
        /// FORTH words:
        /// U.R	( u width -- )	which prints an unsigned number, padded to a certain width
        /// U.	( u -- )	    which prints an unsigned number
        /// .R	( n width -- )	which prints a signed number, padded to a certain width.
        /// </summary>
        [WordName(".R")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("SWAP")]
        [Depends("DUP")]
        [Depends("0<")]
        [Depends("IF")]
        [Depends("NEGATE")]
        [Depends("ROT")]
        [Depends("1-")]
        [Depends("ELSE")]
        [Depends("SWAP")]
        [Depends("THEN")]
        [Depends("UWIDTH")]
        [Depends("SPACES")]
        [Depends("-")]
        [Depends("'A'")]
        [Depends("EMIT")]
        [Depends("U.")]
        [Syntax("( n1 n2 -- )")]
        internal static String DOT_R =
        "  (\n" +
        "    .R prints a signed number, padded to a certain width.  We can't just print the \n" +
        "    sign and call U.R because we want the sign to be next to the number \n" +
        "    ('-123' instead of '-  123').\n" +
        "  )\n" +
        ": .R                       ( n width -- )\n" +
        "    SWAP                   ( width n )\n" +
        "    DUP 0< IF\n" +
        "        NEGATE             ( width u )\n" +
        "        1                  ( save a flag to remember that it was negative | width n 1 )\n" +
        "        SWAP               ( width 1 u )\n" +              //
        "        ROT                ( 1 u width )\n" +              //
        "        1-                 ( 1 u width-1 )\n" +
        "    ELSE\n" +
        "        0                  ( width u 0 )\n" +
        "        SWAP               ( width 0 u )\n" +              //
        "        ROT                ( 0 u width )\n" +              //
        "    THEN\n" +
        "    SWAP                   ( flag width u )\n" +
        "    DUP                    ( flag width u u )\n" +
        "    UWIDTH                 ( flag width u uwidth )\n" +
        "    ROT                    ( flag u uwidth width )\n" +    //
        "    SWAP -                 ( flag u width-uwidth )\n" +
        "    \n" +
        "    SPACES                 ( flag u )\n" +
        "    SWAP                   ( u flag )\n" +
        "    \n" +
        "    IF                     ( was it negative? print the - character )\n" +
        "        'A' EMIT\n" +
        "    THEN\n" +
        "    \n" +
        "    U.\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("ENDCASE")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("BEGIN")]
        [Depends("?DUP")]
        [Depends("WHILE")]
        [Depends("[COMPILE]")]
        [Depends("THEN")]
        [Depends("REPEAT")]
        [Syntax("( x -- )")]
        internal static String END_CASE =
        ": ENDCASE IMMEDIATE\n" +
        "    ['] DROP ,        ( compile DROP )\n" +
        "    \n" +
        "    ( keep compiling THEN until we get to our zero marker )\n" +
        "    BEGIN\n" +
        "        ?DUP\n" +
        "    WHILE\n" +
        "        [COMPILE] THEN\n" +
        "    REPEAT\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("OF")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("IMMEDIATE")]
        [Depends("(")]
        [Depends("[']")]
        [Depends("OVER")]
        [Depends(",")]
        [Depends("=")]
        [Depends("[COMPILE]")]
        [Depends("IF")]
        [Depends("DROP")]
        [Syntax("( x1 x2 -- |x1 )")]
        internal static String OF =
        ": OF IMMEDIATE\n" +
        "    ['] OVER ,        ( compile OVER )\n" +
        "    ['] = ,           ( compile = )\n" +
        "    [COMPILE] IF      ( compile IF )\n" +
        "    ['] DROP ,        ( compile DROP )\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("ENDOF")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("IMMEDIATE")]
        [Depends("[COMPILE]")]
        [Depends("ELSE")]
        [Syntax("( -- )")]
        internal static String END_OF =
        ": ENDOF IMMEDIATE\n" +
        "    [COMPILE] ELSE  ( ENDOF is the same as ELSE )\n" +
        ";\n";

        /// <summary>
        /// Fill Memory with zero's.
        /// </summary>
        [WordName("ERASE")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("FILL")]
        [Syntax("( addr u -- )")]
        internal static String ERASE = ": ERASE ( addr u -- ) 0 FILL ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("HEX")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("BASE")]
        [Depends("!")]
        [Syntax("( -- )")]
        internal static String HEX = ": HEX 16 BASE ! ;\n";

        /// <summary>
        /// 3205 - LITERAL takes whatever is on the stack and compiles LIT &lt;foo&gt;.
        /// </summary>
        [WordName("LITERAL")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("[']")]
        [Depends("LIT")]
        [Depends(",")]
        [Syntax("( -- x )")]
        internal static String LITERAL = ": LITERAL IMMEDIATE ['] LIT , , ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("LSHIFT")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("?DO")]
        [Depends("U2/")]
        [Depends("LOOP")]
        [Syntax("( x1 u -- x2 )")]
        internal static String L_SHIFT = ": LSHIFT ( x1 u -- x2 ) 0 ?DO 2*  LOOP ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("MAX")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("2DUP")]
        [Depends(">")]
        [Depends("IF")]
        [Depends("DROP")]
        [Depends("ELSE")]
        [Depends("SWAP")]
        [Depends("THEN")]
        internal static String MAX =
        "  ( MAX returns the greater of two signed integers )\n" +
        ": MAX\n" +
        "    2DUP > IF DROP ELSE SWAP DROP THEN \n" +
        ";\n";

        /// <summary>
        /// 3572 -
        /// </summary>
        [WordName("MIN")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("2DUP")]
        [Depends("<")]
        [Depends("IF")]
        [Depends("DROP")]
        [Depends("ELSE")]
        [Depends("SWAP")]
        [Depends("THEN")]
        [Syntax("( -- )")]
        internal static String MIN =
        "  ( MIN returns the lesser of two signed integers )\n" +
        ": MIN  ( a b -- n)\n" +
        "    2DUP < IF DROP ELSE SWAP DROP THEN \n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("MOD")]
        [WordSet(WordSets.CORE)]
        [Depends("/MOD")]
        [Depends("DROP")]
        [Syntax("(n1 n2 -- n3)")]
        internal static String MOD =
            ": MOD /MOD DROP ;\n";

        /// <summary>
        /// 3402 Stack.
        /// </summary>
        [WordName("NIP")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("SWAP")]
        [Depends("DROP")]
        [Syntax("( x1 x2 -- x2 )")]
        internal static String NIP = ": NIP ( x1 x2 -- x2 ) SWAP DROP ;\n";

        /// <summary>
        /// 3366 - Inline Comments.
        /// </summary>
        [WordName("(")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("BEGIN")]
        [Depends("KEY")]
        [Depends("DUP")]
        [Depends("'('")]
        [Depends("=")]
        [Depends("IF")]
        [Depends("DROP")]
        [Depends("1+")]
        [Depends("ELSE")]
        [Depends("')'")]
        [Depends("1-")]
        [Depends("THEN")]
        [Depends("0=")]
        [Depends("UNTIL")]
        [Syntax("( cc<paren<: -- )")]
        internal static String PAREN = ": ( IMMEDIATE 1 BEGIN KEY DUP '(' = IF DROP 1+ ELSE ')' = IF 1- THEN THEN DUP 0= UNTIL DROP ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("+LOOP")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("(+LOOP)")]
        [Depends("RESOLVE-DO")]
        [Depends("RESOLVE-LEAVES")]
        [Syntax("( here 0|1 -- )")]
        [Depends("IMMEDIATE")]
        internal static String PLUS_LOOP =
        ": +LOOP   ( here 0|1 -- )\n" +
        "    ['] (+LOOP) ,        \n" +
        "    RESOLVE-DO           \n" +
        "    RESOLVE-LEAVES       \n" +
        "; IMMEDIATE\n";

        /// <summary>
        /// Hidden Helper for ?DO
        /// 
        /// Cleans the loop/limt if equal (but leaves the condition so we can branch correctly).
        /// </summary>
        [WordName("?DOCLEAN")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("DUP")]
        [Depends("IF")]
        [Depends(".S")]
        [Depends("DROP")]
        [Depends("LIT")]
        [Depends("THEN")]
        internal static String QUESTION_DO_CLEAN =
          " : ?DOCLEAN          \n" +
          "   DUP 0= IF         \n" +
          "   DROP DROP DROP    \n" +
          "   0                 ( restore the false condition ) \n" +
          "   THEN              \n" +
          " ;                   \n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("?DO")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("[']")]
        [Depends("2DUP")]
        [Depends(",")]
        [Depends("<>")]
        [Depends("0BRANCH")]
        [Depends("HERE")]
        [Depends("IMMEDIATE")]
        [Depends("?DOCLEAN")]
        [Syntax("( n1|u1 n2|u2 -- ) ( R: -- loop-sys )")]
        internal static String QUESTION_DO =
        "(\n" +
        "  ?DO \n" +
        "	Compilation: ( C: -- do-sys )\n" +
        "   \n" +
        "   Put do-sys onto the control-flow stack. Append the run-time semantics given below \n" +
        "   to the current definition. The semantics are incomplete until resolved by a consumer \n" +
        "   of do-sys such as LOOP.\n" +
        "   \n" +
        "	Run-time: ( n1|u1 n2|u2 -- ) ( R: --  | loop-sys ) \n" +
        "   \n" +
        "   If n1|u1 is equal to n2|u2, continue execution at the location given by the consumer \n" +
        "   of do-sys. Otherwise set up loop control parameters with index n2|u2 and limit n1|u1 \n" +
        "   and continue executing immediately following ?DO. Anything already on the return stack \n" +
        "   becomes unavailable until the loop control parameters are discarded. An ambiguous \n" +
        "   condition exists if n1|u1 and n2|u2 are not both of the same type. \n" +
        ")\n" +
        ": ?DO   ( -- here 1 )\n" +
        "    ['] 2DUP ,    \n" +
        "    ['] <> ,      \n" +
        "    ['] ?DOCLEAN ,\n" + //NEW CODE, Cleans the loop/limt if equal (but leaves the condition so we can branch correctly).
        "    ['] 0BRANCH , \n" +
        "    0 ,           \n" +
        "    ['] (DO) ,    \n" +
        "    HERE 1        \n" +
        "; IMMEDIATE       \n" +
        "\n" +
        "HIDE ?DOCLEAN    \n";

        /// <summary>
        /// RECURSE makes a recursive call to the current word that is being compiled.
        /// </summary>
        [WordName("RECURSE")]
        [WordSet(WordSets.CORE)]
        [Depends("IMMEDIATE")]
        [Depends("LATEST")]
        [Depends("@")]
        [Depends(">CFA")]
        [Depends(",")]
        [Syntax("( -- )")]
        internal static String RECURSE = ": RECURSE IMMEDIATE LATEST @ >CFA , ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("RSHIFT")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("?DO")]
        [Depends("U2/")]
        [Depends("LOOP")]
        [Syntax("( x1 u -- x2 )")]
        internal static String R_SHIFT = ": RSHIFT ( x1 u -- x2 ) 0 ?DO U2/ LOOP ;\n";

        /// <summary>
        /// Math #1 DIV / MOD.
        /// 
        /// The primitive word /MOD (DIVMOD) leaves both the quotient and the remainder on the stack.
        /// </summary>
        [WordName("/")]
        [WordSet(WordSets.CORE)]
        [Depends("/MOD")]
        [Depends("SWAP")]
        [Depends("DROP")]
        [Syntax("(n1 n2 -- n3)")]
        internal static String SLASH_MOD =
            ": / /MOD SWAP DROP ;\n";

        /// <summary>
        /// Tick.
        /// </summary>
        [WordName("'")]
        [WordSet(WordSets.CORE)]
        [Depends("WORD")]
        [Depends("FIND")]
        [Depends(">CFA")]
        [Syntax("( \"<spaces>name\" -- xt )")]
        internal static String TICK = ": ' WORD FIND >CFA ;\n";

        /// <summary>
        /// To Number
        /// </summary>
        [WordName(">NUMBER")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("2DUP")]
        [Depends("-")]
        [Depends(">R")]
        [Depends("?DO")]
        [Depends("DUP")]
        [Depends("C@")]
        [Depends("BASE")]
        [Depends("@")]
        [Depends("DIGIT")]
        [Depends("0=")]
        [Depends("IF")]
        [Depends("DROP")]
        [Depends("LEAVE")]
        [Depends("THEN")]
        [Depends("SWAP")]
        [Depends("@")]
        [Depends("UM*")]
        [Depends("ROT")]
        [Depends("D+")]
        [Depends("R>")]
        [Depends("1+")]
        [Depends("LOOP")]
        [Depends("OVER")]
        internal static String TO_NUMBER =
        ": >NUMBER ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 )\n" +
        "  2DUP + >R 0\n" +
        "  ?DO DUP C@ BASE @ DIGIT 0= IF DROP LEAVE THEN\n" +
        "  SWAP >R SWAP BASE @ UM* DROP ROT BASE @ UM* D+ R> 1+\n" +
        "  LOOP R> OVER -\n" +
        ";\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("TUCK")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("SWAP")]
        [Depends("OVER")]
        [Syntax("( x1 x1 -- x2 x1 x2 )")]
        internal static String TUCK = ": TUCK ( x y -- y x y ) SWAP OVER ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("2@")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("DUP")]
        [Depends("CELL+")]
        [Depends("@")]
        [Depends("SWAP")]
        [Syntax("( a-addr -- x1 x2 )")]
        internal static String TWO_FETCH = ": 2@ ( a-addr -- x1 x2 ) DUP CELL+ @ SWAP @ ;\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("2OVER")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("PICK")]
        [Syntax("( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )")]
        internal static String TWO_OVER = ": 2OVER ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) 3 PICK 3 PICK ;\n";

        /// <summary>
        /// 2R@ Copy cell pair x1 x2 from the return stack.
        /// </summary>
        [WordName("2R@")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("2R>")]
        [Depends("2DUP")]
        [Depends("2>R")]
        [Syntax("( -- x1 x2 ) ( R: x1 x2 -- x1 x2 )")]
        internal static String TWO_R_FETECH = ": 2R@ ( -- x1 x2 ) ( R: x1 x2 -- x1 x2 ) 2R> 2DUP 2>R ;\n";

        /// <summary>
        /// 2R> Transfer cell pair x1 x2 from the return stack.
        /// </summary>
        [WordName("2R>")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("R>")]
        [Depends("SWAP")]
        [Depends("[']")]
        [Depends(",")]
        [Depends("IMMEDIATE")]
        [Syntax("( -- x1 x2 ) ( R: x1 x2 -- )")]
        internal static String TWO_R_FROM = ": 2R> ( -- x1 x2 ) ( R: x1 x2 -- ) ['] R> , ['] R> , ['] SWAP , ; IMMEDIATE\n";

        /// <summary>
        /// 
        /// </summary>
        [WordName("2!")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("SWAP")]
        [Depends("OVER")]
        [Depends("!")]
        [Depends("CELL+")]
        [Syntax("( x1 x2 a-addr -- )")]
        internal static String TWO_STORE =
        ": 2! ( x1 x2 a-addr -- ) SWAP OVER ! CELL+ ! ;\n";

        /// <summary>
        /// 2>R Transfer cell pair x1 x2 to the return stack.
        /// </summary>
        [WordName("2>R")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("R>")]
        [Depends("SWAP")]
        [Depends("[']")]
        [Depends(",")]
        [Depends("IMMEDIATE")]
        [Syntax("( x1 x2 -- ) ( R: -- x1 x2 )")]
        internal static String TWO_TO_R = ": 2>R ( x1 x2 -- ) ( R: -- x1 x2 ) ['] SWAP , ['] >R , ['] >R , ; IMMEDIATE\n";

        /// <summary>
        /// Number Printing.
        /// </summary>
        [WordName("U.")]
        [WordSet(WordSets.CORE)]
        [Depends("(")]
        [Depends("BASE")]
        [Depends("@")]
        [Depends("U/MOD")]
        [Depends("?DUP")]
        [Depends("IF")]
        [Depends("RECURSE")]
        [Depends("THEN")]
        [Depends("DUP")]
        [Depends("<")]
        [Depends("'0'")]
        [Depends("ELSE")]
        [Depends("'A'")]
        [Depends("EMIT")]
        [Syntax("( u -- )")]
        internal static String U_DOT =
            "  ( This is the underlying recursive definition of U. )\n" +
            ": U.                     ( u -- )\n" +
            "    BASE @ U/MOD           ( width rem quot )\n" +
            "    ?DUP IF                ( if quotient <> 0 then )\n" +
            "        RECURSE            ( print the quotient )\n" +
            "    THEN\n" +
            "    \n" +
            "    ( print the remainder )\n" +
            "    DUP 10 < IF\n" +
            "        '0'                ( decimal digits 0..9 )\n" +
            "    ELSE\n" +
            "        10 -               ( hex and beyond digits A..Z )\n" +
            "        'A'\n" +
            "    THEN\n" +
            "    +\n" +
            "    EMIT\n" +
            ";\n";

        /// <summary>
        /// The standard FORTH word . (DOT) is very important.  It takes the number at the top
        /// of the stack and prints it out.  However first I'm going to implement some lower-level
        /// FORTH words:
        /// U.R	( u width -- )	which prints an unsigned number, padded to a certain width
        /// U.	( u -- )	    which prints an unsigned number
        /// .R	( n width -- )	which prints a signed number, padded to a certain width.
        /// </summary>
        [WordName("U.R")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("SWAP")]
        [Depends("DUP")]
        [Depends("UWIDTH")]
        [Depends("ROT")]
        [Depends("-")]
        [Depends("SPACES")]
        [Depends("U.")]
        [Syntax("( u n -- )")]
        internal static String U_DOT_R =
        ": U.R                      ( u width -- )\n" +
        "    SWAP                   ( width u )\n" +
        "    DUP                    ( width u u )\n" +
        "    UWIDTH                 ( width u uwidth )\n" +
        "    ROT                    ( u uwidth width )\n" +
        "    SWAP -                 ( u width-uwidth )\n" +
        "                           ( At this point if the requested width is narrower, we'll have a negative number on \n" +
        "                             the stack. Otherwise the number on the stack is the number of spaces to print. \n" +
        "                             But SPACES won't print a negative number of spaces anyway, so it's now safe \n" +
        "                             to call SPACES ...\n" +
        "                           )\n" +
        "    SPACES\n" +
        "                           ( ... and then call the underlying implementation of U. )\n" +
        "    U.\n" +
        ";\n";

        /// <summary>
        /// 3572
        /// </summary>
        [WordName("WITHIN")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("(")]
        [Depends("ROT")]
        [Depends("OVER")]
        [Depends("<=")]
        [Depends("IF")]
        [Depends(">")]
        [Depends("ELSE")]
        [Depends("2DROP")]
        [Depends("FALSE")]
        [Depends("THEN")]
        [Syntax("( n1|u1 n2|u2 n3|u3 -- flag )")]
        internal static String WITHIN =
        "  ( c a b WITHIN returns true if a <= c and c < b )\n" +
        ": WITHIN\n" +
        "    ROT                    ( b c a )\n" +
        "    OVER                   ( b c a c )\n" +
        "    <= IF\n" +
        "        >                  ( b c -- TRUE/FALSE )\n" +
        "    ELSE\n" +
        "        2DROP              ( b c --  FALSE)\n" +
        "        FALSE\n" +
        "    THEN\n" +
        ";\n";

        /// <summary>
        /// PAD
        /// </summary>
        [WordName("PAD")]
        [WordSet(WordSets.CORE_EXT)]
        [Depends("CREATE")]
        [Depends("CHARS")]
        [Depends("ALLOT")]
        [Syntax("( -- c-addr )")]
        internal static String PAD = "CREATE PAD " + Forth.PAD_SIZE.ToString() + " CHARS ALLOT\n";

        #endregion Fields
    }
}